from __future__ import print_function

from Queue import Queue
from threading import Thread


import logmanager
import logging
import traceback

class Worker(Thread):
	"""Thread executing tasks from a given tasks queue"""
	def __init__(self, tasks, loggerName, getHandle):
		Thread.__init__(self)
		self.tasks = tasks
		self.daemon = True
		self.log = logging.getLogger(loggerName)
		self.getHandle = getHandle
		self.start()

		self.x = "Hello"
	def logPrint(self, *args):
		self.log.info(args)
	def logErr(self, *args):
		self.log.error(args)
		
	def run(self):
		while True:
			func, args, kwargs = self.tasks.get()
			#print("Running Task")
			#print("args", args)
			#print(" kwargs ", kwargs )
			#modify kwargs for threading
			kwargs["getHandle"]	=	self.getHandle
			kwargs["logPrint"]	=	self.logPrint
			kwargs["logErr"]	=	self.logErr
			#print("Running Task")

			try:
				func(self, *args,**kwargs)

			#print("ran Task")
			except Exception, e:
				print(e)
				traceback.print_exc()
			self.tasks.task_done()

class ThreadPool:
	"""Pool of threads consuming tasks from a queue"""
	def __init__(self, numThreads, webFuncs):

		if len(webFuncs) != numThreads:
			raise ValueError
		#print(numThreads)
		self.loggerNames = logmanager.initThreadLogging(numThreads)
		self.tasks = Queue(numThreads)
		self.workers = []
		for x in range(numThreads):
			self.workers.append(Worker(self.tasks, self.loggerNames[x], webFuncs[x]))

	def addTask(self, func, *args, **kargs):
		"""Add a task to the queue"""
		
		#print("Popping Task")

		self.tasks.put((func, args, kargs))

	def waitCompletion(self):
		"""Wait for completion of all the tasks in the queue"""
		self.tasks.join()
